jQuery(document).ready(function(){
// 	jQuery('input:text , input:password').not(jQuery(".searchFieldInput")).not(jQuery(".photoDesc")).addClass('inputClass');
	
	jQuery("#search_discount").hint();
	jQuery("#search_events").hint();
	jQuery("#coupons_newsletter").hint();

	jQuery('#discount_tab').hover(showDiscountPopup_div, hideDiscountPopup_div);
	jQuery('#discount_popup').hover(showDiscountPopup_div, hideDiscountPopup_div);

	jQuery('#event_tab').hover(showEventPopup_div, hideEventPopup_div);
	jQuery('#event_popup').hover(showEventPopup_div, hideEventPopup_div);
});

function submitcomment(event) {
	if (window.event && window.event.keyCode == 13) {
		submit_comment();
		return false;
	}
	else if (event && event.which == 13) {
		submit_comment();
		return false;
	}
	else
		return true;
}

function submitpricelist(event) {
	if (window.event && window.event.keyCode == 13) {
		submit_pricelist();
		return false;
	}
	else if (event && event.which == 13) {
		submit_pricelist();
		return false;
	}
	else
		return true;
}

function submitbloglink(event) {
	if (window.event && window.event.keyCode == 13) {
		submit_bloglink();
		return false;
	}
	else if (event && event.which == 13) {
		submit_bloglink();
		return false;
	}
	else
		return true;
}

function showSearchOption(type) {
	if (jQuery("#searchOption"+type).css('display') == "none") {
		jQuery('#searchOption'+type).show();
	}
	else {
		jQuery('#searchOption'+type).hide();
	}
}

function selectSearchOption (optionvalue,type) {
	jQuery('#searchOption'+type).hide();
	jQuery('#SearchOptionText'+type).text(optionvalue);
	jQuery('#discountperiod'+type).val(optionvalue);
	
	if (type == "4") {
		jQuery('.emailPanelWord b').text(optionvalue);
	}
}

function strip_character(fieldid) {
	var field_value = jQuery('#'+fieldid).val();
	field_value = field_value.replace(' ','');
	field_value = field_value.replace('&','');
	field_value = field_value.replace('?','');
	field_value = field_value.replace('=','');
	
	jQuery('#'+fieldid).val(field_value);
}

function tongleLoginWindow () {
	if (jQuery("#loginWindow").css('display') == "none") {
		jQuery('#loginWindow').fadeIn();
		jQuery('#login_username').focus();
	}
	else {
		jQuery('#loginWindow').fadeOut();
	}
}

function register_member(code)
{
	var fullname = jQuery("#register_fullname").val();
	var phone = jQuery("#register_phone").val();
	var emailaddress = jQuery("#register_emailaddress").val();
	var emailaddress1 = jQuery("#register_emailaddress1").val();
	var username = jQuery("#register_username").val();
	var state = jQuery("#register_state").val();
	var area = jQuery("#register_area").val();
	var password1 = jQuery("#register_password1").val();
	var password2 = jQuery("#register_password2").val();
	var source = jQuery("#register_source").val();
	var keyword = jQuery("#register_keyword").val();
	var pictureid = jQuery("#register_pictureid").val();
	var error_flag = "0";

	if (fullname == ""){
		jQuery("#register_div_error_text").text('Invalid Full Name. Full Name can not be blank.');
		jQuery("#register_div_error").fadeIn();
		jQuery("#register_fullname").focus();
		error_flag = "1";
		setTimeout("jQuery('#register_div_error').fadeOut()",5000);
	}
	else if (emailaddress == ""){
		jQuery("#register_div_error_text").text('Invalid Email Address. Email Address can not be blank.');
		jQuery("#register_div_error").fadeIn();
		jQuery("#register_emailaddress").focus();
		error_flag = "1";
		setTimeout("jQuery('#register_div_error').fadeOut()",5000);
	}
	else if (emailaddress != emailaddress1){
		jQuery("#register_div_error_text").text('Please double check your Email Address. Re-Enter Email Address does not Match.');
		jQuery("#register_div_error").fadeIn();
		jQuery("#register_emailaddress").focus();
		error_flag = "1";
		setTimeout("jQuery('#register_div_error').fadeOut()",5000);
	}
	else if (area == ""){
		jQuery("#register_div_error_text").text('Invalid Area. Area can not be blank.');
		jQuery("#register_div_error").fadeIn();
		jQuery("#register_area").focus();
		error_flag = "1";
		setTimeout("jQuery('#register_div_error').fadeOut()",5000);
	}
	else if (username == ""){
		jQuery("#register_div_error_text").text('Invalid Username. Username can not be blank.');
		jQuery("#register_div_error").fadeIn();
		jQuery("#register_username").focus();
		error_flag = "1";
		setTimeout("jQuery('#register_div_error').fadeOut()",5000);
	}
	else if (password1 == ""){
		jQuery("#register_div_error_text").text('Invalid Password. Password can not be blank.');
		jQuery("#register_div_error").fadeIn();
		error_flag = "1";
		setTimeout("jQuery('#register_div_error').fadeOut()",5000);
	}
	else if (password1 != password2){
		jQuery("#register_div_error_text").text('Password & Confirm Password Does not match.');
		jQuery("#register_div_error").fadeIn();
		error_flag = "1";
		setTimeout("jQuery('#register_div_error').fadeOut()",5000);
	}	
	else if (keyword == ""){
		jQuery("#register_div_error_text").text('Invalid Word verification.');
		jQuery("#register_div_error").fadeIn();
		error_flag = "1";
		setTimeout("jQuery('#register_div_error').fadeOut()",5000);
	}
	
	if (error_flag != "1") {
		jQuery("#register_button").hide();
		jQuery("#register_ajax_loading").show();
	
		if (code == "PG") {
			var register_member_url = "/cgi-bin/everydaypg/register_member.pl";
			var successful_url = '/penang/register_successful.shtml';
		}
		else if (code == "KL") {
			var register_member_url = "/cgi-bin/everyday/register_member.pl";
			var successful_url = '/register_successful.shtml';
		}
	
		jQuery.post(register_member_url , {"fullname": fullname, "phone": phone, "emailaddress": emailaddress, "username": username,"password": password1, "keyword": keyword, "pictureid": pictureid, "state": state, "area": area, "source": source }, function(xml){
		     jQuery(xml).find('result').each(function(){
		        var status = jQuery("status", this).text();
		        var message = jQuery("message", this).text();
	
				if (status == "Error") {
					jQuery("#register_div_error_text").text(message);
					jQuery("#register_div_error").fadeIn();
	
					jQuery("#register_button").show();
					jQuery("#register_ajax_loading").hide();
	
					setTimeout("jQuery('#register_div_error').fadeOut()",5000);
				}
				else {
					document.location.href=successful_url;
				}
		    });
		});
	}
}

function user_login(code)
{
	var username = jQuery("#login_username").val();
	var password = jQuery("#login_password").val();
	var error_flag = "0";

	if (code == "KL") {
		var posturl = "/cgi-bin/everyday/login.pl";
		var redirect = "/index.shtml";
	}
	else if (code == "PG") {
		var posturl = "/cgi-bin/everydaypg/login.pl";
		var redirect = "/penang/index.shtml";
	}

	if (username == ""){
		jQuery("#error_login_text").text('Invalid Username.');
		jQuery("#error_login").fadeIn();
		error_flag = "1";
		setTimeout("jQuery('#error_login').fadeOut()",5000);
	}
	else if (password == ""){
		jQuery("#error_login_text").text('Invalid Password.');
		jQuery("#error_login").fadeIn();
		error_flag = "1";
		setTimeout("jQuery('#error_login').fadeOut()",5000);
	}

	if (error_flag != "1") {
		jQuery("#login_button").hide();
		jQuery("#login_ajax_loading").show();
	
		jQuery.post(posturl, {"username": username, "password": password }, function(xml){
		     jQuery(xml).find('result').each(function(){
		        var status = jQuery("status", this).text();
		        var message = jQuery("message", this).text();
	
				if (status == "Error") {
					jQuery("#error_login_text").text(message);
					jQuery("#error_login").fadeIn();
	
					jQuery("#login_button").show();
					jQuery("#login_ajax_loading").hide();
	
					setTimeout("jQuery('#error_login').fadeOut()",5000);
				}
				else if (status == "Activate") {
					document.location.href='/activate_account.shtml?error=1';
				}
				else {
					var redirecturl = jQuery("#redirecturl").val();

					if (redirecturl == "myprofile")
						document.location.href = '/member/'+username+'';
					else if (redirecturl == "refresh")
						document.location.reload();
					else if (redirecturl)
						document.location.href = redirecturl;
					else
						document.location.href = redirect;
				}
		    });
		});
	}
}

function tonglediv(div1,div2) {
	if (jQuery('#'+div1).css('display') == "none") {
		jQuery('#'+div2).hide();
		jQuery('#'+div1).fadeIn();
	}
	else if (jQuery('#'+div2).css('display') == "none") {
		jQuery('#'+div2).fadeIn();
		jQuery('#'+div1).hide();
	}
}

function showeyes() {
	jQuery('#everyday_eyes').fadeIn(500);
}

function hideeyes() {
	jQuery('#everyday_eyes').fadeOut();
}

function showDiscountPopup_div() {
	setTimeout("showDiscountPopup_div_delay()",300);
	jQuery('#discount_popup_counter').val('1');
}

function showDiscountPopup_div_delay() {
	if (jQuery('#discount_popup').css('display') == "none" && (jQuery('#discount_popup_counter').val() == "1")) {
		var discount_pop_t = jQuery("#discount_tab").offset().top;
		var discount_pop_l = jQuery("#discount_tab").offset().left;
		jQuery('#discount_popup').css('top',discount_pop_t + 21);
		jQuery('#discount_popup').css('left',discount_pop_l);
		jQuery('#discount_popup').show();
	}
}

function hideDiscountPopup_div() {
	setTimeout("hideDiscountPopup_div_delay()",500);
	jQuery('#discount_popup_counter').val('0');
}

function hideDiscountPopup_div_delay() {
	if (jQuery('#discount_popup').css('display') != "none" && (jQuery('#discount_popup_counter').val() == "0")) {
		jQuery('#discount_popup').hide();
	}
}

function showEventPopup_div() {
	setTimeout("showEventPopup_div_delay()",300);
	jQuery('#event_popup_counter').val('1');
}

function showEventPopup_div_delay() {
	if (jQuery('#event_popup').css('display') == "none" && (jQuery('#event_popup_counter').val() == "1")) {
		var event_pop_t = jQuery("#event_tab").offset().top;
		var event_pop_l = jQuery("#event_tab").offset().left;
		jQuery('#event_popup').css('top',event_pop_t + 21);
		jQuery('#event_popup').css('left',event_pop_l);
		jQuery('#event_popup').show();
	}
}

function hideEventPopup_div() {
	setTimeout("hideEventPopup_div_delay()",500);
	jQuery('#event_popup_counter').val('0');
}

function hideEventPopup_div_delay() {
	if (jQuery('#event_popup').css('display') != "none" && (jQuery('#event_popup_counter').val() == "0")) {
		jQuery('#event_popup').hide();
	}
}

function enter_login(event) {
	if (window.event && window.event.keyCode == 13)
    	user_login('KL');
	else if (event && event.which == 13)
	    user_login('KL');
	else
	    return true;
}

function selecttab(fieldid,no) {
	for (i=0;i <= 5;i++) {
		jQuery('#'+fieldid+'_'+i).hide();

		if (fieldid == "active_sales" || fieldid == "pricelist" || fieldid == "active_event") {
			jQuery('#link_'+fieldid+'_'+i).attr('class','');
		}
		else {
			jQuery('#link_'+fieldid+'_'+i).attr('class','notselected');
		}
	}
	
	jQuery('#'+fieldid+'_'+no).show();
	if (fieldid == "active_sales" || fieldid == "pricelist" || fieldid == "active_event") {
		jQuery('#link_'+fieldid+'_'+no).addClass('selected');
	}
	else {
		jQuery('#link_'+fieldid+'_'+no).attr('class','selected');
	}
}

function ec_submit_email() {
	emailaddress = jQuery("#coupons_newsletter").val();
	state = jQuery("#discountperiod4").val();
	
	if(!check_email(emailaddress)){
		alert("Invalid Email Address");
		jQuery("#coupons_newsletter").focus(); 
	}
	else {
		jQuery.post('/cgi-bin/everyday/ec_register_email.pl', {"emailaddress": emailaddress, "state": state }, function(xml){
		     jQuery(xml).find('result').each(function(){
		        var status = jQuery("status", this).text();
		        var message = jQuery("message", this).text();
	
				if (status == "Error") {
					alert(message);
				}
				else {
					document.location.href = '/coupons/index.php?page=newsletter_successful&email='+emailaddress+'&state='+message;
				}
		    });
		});
	}
}

function check_email(e) {
	ok = "1234567890qwertyuiop[]asdfghjklzxcvbnm.@-_QWERTYUIOPASDFGHJKLZXCVBNM";
	
	for(i=0; i < e.length ;i++){
		if(ok.indexOf(e.charAt(i))<0){ 
			return (false);
		}	
	} 
		
	if (document.images) {
		re = /(@.*@)|(\.\.)|(^\.)|(^@)|(@$)|(\.$)|(@\.)/;
		re_two = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
		if (!e.match(re) && e.match(re_two)) {
			return (-1);		
		} 
	}
}


/**
* hoverIntent is similar to jQuery's built-in "hover" function except that
* instead of firing the onMouseOver event immediately, hoverIntent checks
* to see if the user's mouse has slowed down (beneath the sensitivity
* threshold) before firing the onMouseOver event.
* 
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
* 
* hoverIntent is currently available for use in all personal or commercial 
* projects under both MIT and GPL licenses. This means that you can choose 
* the license that best suits your project, and use it accordingly.
* 
* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
* $("ul li").hoverIntent( showNav , hideNav );
* 
* // advanced usage receives configuration object only
* $("ul li").hoverIntent({
*	sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)
*	interval: 100,   // number = milliseconds of polling interval
*	over: showNav,  // function = onMouseOver callback (required)
*	timeout: 0,   // number = milliseconds delay before onMouseOut function call
*	out: hideNav    // function = onMouseOut callback (required)
* });
* 
* @param  f  onMouseOver function || An object with configuration options
* @param  g  onMouseOut function  || Nothing (use configuration options object)
* @author    Brian Cherne <brian@cherne.net>
*/
(function($) {
	$.fn.hoverIntent = function(f,g) {
		// default configuration options
		var cfg = {
			sensitivity: 7,
			interval: 100,
			timeout: 0
		};
		// override configuration options with user supplied object
		cfg = $.extend(cfg, g ? { over: f, out: g } : f );

		// instantiate variables
		// cX, cY = current X and Y position of mouse, updated by mousemove event
		// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
		var cX, cY, pX, pY;

		// A private function for getting mouse position
		var track = function(ev) {
			cX = ev.pageX;
			cY = ev.pageY;
		};

		// A private function for comparing current and previous mouse position
		var compare = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			// compare mouse positions to see if they've crossed the threshold
			if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
				$(ob).unbind("mousemove",track);
				// set hoverIntent state to true (so mouseOut can be called)
				ob.hoverIntent_s = 1;
				return cfg.over.apply(ob,[ev]);
			} else {
				// set previous coordinates for next time
				pX = cX; pY = cY;
				// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
				ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
			}
		};

		// A private function for delaying the mouseOut function
		var delay = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			ob.hoverIntent_s = 0;
			return cfg.out.apply(ob,[ev]);
		};

		// A private function for handling mouse 'hovering'
		var handleHover = function(e) {
			// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
			while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
			if ( p == this ) { return false; }

			// copy objects to be passed into t (required for event object to be passed in IE)
			var ev = jQuery.extend({},e);
			var ob = this;

			// cancel hoverIntent timer if it exists
			if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }

			// else e.type == "onmouseover"
			if (e.type == "mouseover") {
				// set "previous" X and Y position based on initial entry point
				pX = ev.pageX; pY = ev.pageY;
				// update "current" X and Y position based on mousemove
				$(ob).bind("mousemove",track);
				// start polling interval (self-calling timeout) to compare mouse coordinates over time
				if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}

			// else e.type == "onmouseout"
			} else {
				// unbind expensive mousemove event
				$(ob).unbind("mousemove",track);
				// if hoverIntent state is true, then call the mouseOut function after the specified delay
				if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
			}
		};

		// bind the function to the two event listeners
		return this.mouseover(handleHover).mouseout(handleHover);
	};
})(jQuery);

/*
highlight v1

Highlights arbitrary terms.

<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>

MIT license.

Johann Burkard
<http://johannburkard.de>
<mailto:jb@eaio.com>

*/

$(function() {
 jQuery.highlight = document.body.createTextRange ?

/*
Version for IE using TextRanges.
*/
 function(node, te,classname) {
 var r = document.body.createTextRange();
 r.moveToElementText(node);
 for (var i = 0; r.findText(te); i++) {
 r.pasteHTML('<span class="'+ classname +'">' + r.text + '<\/span>');
 r.collapse(false);
 }
 }

 :

/*
 (Complicated) version for Mozilla and Opera using span tags.
*/
 function(node, te, classname) {
 var pos, skip, spannode, middlebit, endbit, middleclone;
 skip = 0;
 if (node.nodeType == 3) {
 pos = node.data.toUpperCase().indexOf(te);
 if (pos >= 0) {
 spannode = document.createElement('span');
 spannode.className = classname;
 middlebit = node.splitText(pos);
 endbit = middlebit.splitText(te.length);
 middleclone = middlebit.cloneNode(true);
 spannode.appendChild(middleclone);
 middlebit.parentNode.replaceChild(spannode, middlebit);
 skip = 1;
 }
 }
 else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
 for (var i = 0; i < node.childNodes.length; ++i) {
 i += $.highlight(node.childNodes[i], te,classname);
 }
 }
 return skip;
 }

 ;
});

jQuery.fn.removeHighlight = function() {
 return this.find("span.highlight").each(function() {
 this.parentNode.replaceChild(this.firstChild, this).normalize();
 });
};

/*
 * timeago: a jQuery plugin, version: 0.5.1 (08/20/2008)
 * @requires jQuery v1.2 or later
 *
 * Timeago is a jQuery plugin that makes it easy to support automatically
 * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
 *
 * For usage and examples, visit:
 * http://timeago.yarp.com/
 *
 * Licensed under the MIT:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright (c) 2008, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org)
 */
(function($) {
  $.timeago = function(timestamp) {
    if (timestamp instanceof Date) return inWords(timestamp);
    else if (typeof timestamp == "string") return inWords($.timeago.parse(timestamp));
    else return inWords($.timeago.parse($(timestamp).attr("title")));
  };
  var $t = $.timeago;

  $.extend($.timeago, {
    settings: {
      refreshMillis: 60000,
      allowFuture: false,
      strings: {
        ago: "ago",
        fromNow: "from now",
        seconds: "less than a minute",
        minute: "about a minute",
        minutes: "%d minutes",
        hour: "about an hour",
        hours: "about %d hours",
        day: "a day",
        days: "%d days",
        month: "about a month",
        months: "%d months",
        year: "about a year",
        years: "%d years"
      }
    },
    inWords: function(distanceMillis) {
      var $l = this.settings.strings;
      var suffix = $l.ago;
      if (this.settings.allowFuture) {
        if (distanceMillis < 0) suffix = $l.fromNow;
        distanceMillis = Math.abs(distanceMillis);
      }

      var seconds = distanceMillis / 1000;
      var minutes = seconds / 60;
      var hours = minutes / 60;
      var days = hours / 24;
      var years = days / 365;

      var words = seconds < 45 && sprintf($l.seconds, Math.round(seconds)) ||
        seconds < 90 && $l.minute ||
        minutes < 45 && sprintf($l.minutes, Math.round(minutes)) ||
        minutes < 90 && $l.hour ||
        hours < 24 && sprintf($l.hours, Math.round(hours)) ||
        hours < 48 && $l.day ||
        days < 30 && sprintf($l.days, Math.floor(days)) ||
        days < 60 && $l.month ||
        days < 365 && sprintf($l.months, Math.floor(days / 30)) ||
        years < 2 && $l.year ||
        sprintf($l.years, Math.floor(years));

      return words + " " + suffix;
    },
    parse: function(iso8601) {
      var s = $.trim(iso8601);
      s = s.replace(/-/,"/").replace(/-/,"/");
      s = s.replace(/T/," ").replace(/Z/," UTC");
      s = s.replace(/([\+-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
      return new Date(s);
    }
  });

  $.fn.timeago = function() {
    var self = this;
    self.each(refresh);

    var $s = $t.settings;
    if ($s.refreshMillis > 0) {
      setInterval(function() { self.each(refresh); }, $s.refreshMillis);
    }
    return self;
  };

  function refresh() {
    var date = $t.parse(this.title);
    if (!isNaN(date)) {
      $(this).text(inWords(date));
    }
    return this;
  }

  function inWords(date) {
    return $t.inWords(distance(date));
  }

  function distance(date) {
    return (new Date().getTime() - date.getTime());
  }

  // lame sprintf implementation
  function sprintf(string, value) {
    return string.replace(/%d/i, value);
  }

  // fix for IE6 suckage
  if ($.browser.msie && $.browser.version < 7.0) {
    document.createElement('abbr');
  }
})(jQuery);

jQuery.extend({
    createUploadIframe: function(id, uri)
	{
			//create frame
            var frameId = 'jUploadFrame' + id;
            
            if(window.ActiveXObject) {
                var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
                if(typeof uri== 'boolean'){
                    io.src = 'javascript:false';
                }
                else if(typeof uri== 'string'){
                    io.src = uri;
                }
            }
            else {
                var io = document.createElement('iframe');
                io.id = frameId;
                io.name = frameId;
            }
            io.style.position = 'absolute';
            io.style.top = '-1000px';
            io.style.left = '-1000px';

            document.body.appendChild(io);

            return io			
    },
    createUploadForm: function(id, fileElementId, fileClass)
	{
		//create form	
		var formId = 'jUploadForm' + id;
		var fileId = 'jUploadFile' + id;
		var form = jQuery('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');	
		jQuery("."+fileClass).each(function() {
			var oldElement = jQuery('#' + this.id);
			var newElement = jQuery(oldElement).clone();
			jQuery(oldElement).attr('id', fileId);
			jQuery(oldElement).before(newElement);
			jQuery(oldElement).appendTo(form);
		});
		
		//set attributes
		jQuery(form).css('position', 'absolute');
		jQuery(form).css('top', '-1200px');
		jQuery(form).css('left', '-1200px');
		jQuery(form).appendTo('body');
		return form;
    },

    ajaxFileUpload: function(s) {
        // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout		
        s = jQuery.extend({}, jQuery.ajaxSettings, s);
        var id = new Date().getTime()        
		var form = jQuery.createUploadForm(id, s.fileElementId, s.fileClass);
		var io = jQuery.createUploadIframe(id, s.secureuri);
		var frameId = 'jUploadFrame' + id;
		var formId = 'jUploadForm' + id;		
        // Watch for a new set of requests
        if ( s.global && ! jQuery.active++ )
		{
			jQuery.event.trigger( "ajaxStart" );
		}            
        var requestDone = false;
        // Create the request object
        var xml = {}   
        if ( s.global )
            jQuery.event.trigger("ajaxSend", [xml, s]);
        // Wait for a response to come back
        var uploadCallback = function(isTimeout)
		{			
			var io = document.getElementById(frameId);
            try 
			{				
				if(io.contentWindow)
				{
					 xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
                	 xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
					 
				}else if(io.contentDocument)
				{
					 xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
                	xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
				}						
            }catch(e)
			{
				jQuery.handleError(s, xml, null, e);
			}
            if ( xml || isTimeout == "timeout") 
			{				
                requestDone = true;
                var status;
                try {
                    status = isTimeout != "timeout" ? "success" : "error";
                    // Make sure that the request was successful or notmodified
                    if ( status != "error" )
					{
                        // process the data (runs the xml through httpData regardless of callback)
                        var data = jQuery.uploadHttpData( xml, s.dataType );    
                        // If a local callback was specified, fire it and pass it the data
                        if ( s.success )
                            s.success( data, status );
    
                        // Fire the global callback
                        if( s.global )
                            jQuery.event.trigger( "ajaxSuccess", [xml, s] );
                    } else
                        jQuery.handleError(s, xml, status);
                } catch(e) 
				{
                    status = "error";
                    jQuery.handleError(s, xml, status, e);
                }

                // The request was completed
                if( s.global )
                    jQuery.event.trigger( "ajaxComplete", [xml, s] );

                // Handle the global AJAX counter
                if ( s.global && ! --jQuery.active )
                    jQuery.event.trigger( "ajaxStop" );

                // Process result
                if ( s.complete )
                    s.complete(xml, status);

                jQuery(io).unbind()

                setTimeout(function()
									{	try 
										{
											jQuery(io).remove();
											jQuery(form).remove();	
											
										} catch(e) 
										{
											jQuery.handleError(s, xml, null, e);
										}									

									}, 100)

                xml = null

            }
        }
        // Timeout checker
        if ( s.timeout > 0 ) 
		{
            setTimeout(function(){
                // Check to see if the request is still happening
                if( !requestDone ) uploadCallback( "timeout" );
            }, s.timeout);
        }
        try 
		{
           // var io = $('#' + frameId);
			var form = jQuery('#' + formId);
			jQuery(form).attr('action', s.url);
			jQuery(form).attr('method', 'POST');
			jQuery(form).attr('target', frameId);
            if(form.encoding)
			{
                form.encoding = 'multipart/form-data';				
            }
            else
			{				
                form.enctype = 'multipart/form-data';
            }			
            jQuery(form).submit();

        } catch(e) 
		{			
            jQuery.handleError(s, xml, null, e);
        }
        if(window.attachEvent){
            document.getElementById(frameId).attachEvent('onload', uploadCallback);
        }
        else{
            document.getElementById(frameId).addEventListener('load', uploadCallback, false);
        } 		
        return {abort: function () {}};	

    },

    uploadHttpData: function( r, type ) {
        var data = !type;
        data = type == "xml" || data ? r.responseXML : r.responseText;
        // If the type is "script", eval it in global context
        if ( type == "script" )
            jQuery.globalEval( data );
        // Get the JavaScript object, if JSON is used.
        if ( type == "json" )
            eval( "data = " + data );
        // evaluate scripts within html
        if ( type == "html" )
            jQuery("#"+return_id).html(data).evalScripts();
			//alert($('param', data).each(function(){alert($(this).attr('value'));}));
        return data;
    }
})

jQuery.imgAreaSelect={onKeyPress:null};jQuery.imgAreaSelect.init=function(img,options){var $area=jQuery('<div></div>'),$border1=jQuery('<div></div>'),$border2=jQuery('<div></div>'),$outLeft=jQuery('<div></div>'),$outTop=jQuery('<div></div>'),$outRight=jQuery('<div></div>'),$outBottom=jQuery('<div></div>'),left,top,imgOfs,imgWidth,imgHeight,parent,parOfs,parScroll,adjusted,zIndex=2000,fixed,$p,startX,startY,moveX,moveY,resizeMargin=10,resize=[],V=0,H=1,keyDown,d,aspectRatio,x1,x2,y1,y2,x,y,selection={x1:0,y1:0,x2:0,y2:0,width:0,height:0};var $a=$area.add($border1).add($border2);var $o=$outLeft.add($outTop).add($outRight).add($outBottom);function viewX(x){return x+imgOfs.left+parScroll.left-parOfs.left}function viewY(y){return y+imgOfs.top+parScroll.top-parOfs.top}function selX(x){return x-imgOfs.left-parScroll.left+parOfs.left}function selY(y){return y-imgOfs.top-parScroll.top+parOfs.top}function evX(event){return event.pageX+parScroll.left-parOfs.left}function evY(event){return event.pageY+parScroll.top-parOfs.top}function adjust(){imgOfs=jQuery(img).offset();imgWidth=jQuery(img).width();imgHeight=jQuery(img).height();if(jQuery(parent).is('body'))parOfs=parScroll={left:0,top:0};else{parOfs=jQuery(parent).offset();parScroll={left:parent.scrollLeft,top:parent.scrollTop}}left=viewX(0);top=viewY(0)}function update(resetKeyPress){$a.css({left:viewX(selection.x1)+'px',top:viewY(selection.y1)+'px',width:Math.max(selection.width-options.borderWidth*2,0)+'px',height:Math.max(selection.height-options.borderWidth*2,0)+'px'});$outLeft.css({left:left+'px',top:top+'px',width:selection.x1+'px',height:imgHeight+'px'});$outTop.css({left:left+selection.x1+'px',top:top+'px',width:selection.width+'px',height:selection.y1+'px'});$outRight.css({left:left+selection.x2+'px',top:top+'px',width:imgWidth-selection.x2+'px',height:imgHeight+'px'});$outBottom.css({left:left+selection.x1+'px',top:top+selection.y2+'px',width:selection.width+'px',height:imgHeight-selection.y2+'px'});if(resetKeyPress!==false){if(jQuery.imgAreaSelect.keyPress!=docKeyPress)jQuery(document).unbind(jQuery.imgAreaSelect.keyPress,jQuery.imgAreaSelect.onKeyPress);if(options.keys)jQuery(document).bind(jQuery.imgAreaSelect.keyPress,jQuery.imgAreaSelect.onKeyPress=docKeyPress)}}function areaMouseMove(event){if(!adjusted){adjust();adjusted=true;$a.one('mouseout',function(){adjusted=false})}x=selX(evX(event))-selection.x1;y=selY(evY(event))-selection.y1;resize=[];if(options.resizable){if(y<=resizeMargin)resize[V]='n';else if(y>=selection.height-resizeMargin)resize[V]='s';if(x<=resizeMargin)resize[H]='w';else if(x>=selection.width-resizeMargin)resize[H]='e'}$border2.css('cursor',resize.length?resize.join('')+'-resize':options.movable?'move':'')}function areaMouseDown(event){if(event.which!=1)return false;adjust();if(options.resizable&&resize.length>0){jQuery('body').css('cursor',resize.join('')+'-resize');x1=viewX(resize[H]=='w'?selection.x2:selection.x1);y1=viewY(resize[V]=='n'?selection.y2:selection.y1);jQuery(document).mousemove(selectingMouseMove);$border2.unbind('mousemove',areaMouseMove);jQuery(document).one('mouseup',function(){resize=[];jQuery('body').css('cursor','');if(options.autoHide)$a.add($o).hide();options.onSelectEnd(img,selection);jQuery(document).unbind('mousemove',selectingMouseMove);$border2.mousemove(areaMouseMove)})}else if(options.movable){moveX=selection.x1+left;moveY=selection.y1+top;startX=evX(event);startY=evY(event);jQuery(document).mousemove(movingMouseMove).one('mouseup',function(){options.onSelectEnd(img,selection);jQuery(document).unbind('mousemove',movingMouseMove)})}else jQuery(img).mousedown(event);return false}function aspectRatioXY(){x2=Math.max(left,Math.min(left+imgWidth,x1+Math.abs(y2-y1)*aspectRatio*(x2>=x1?1:-1)));y2=Math.round(Math.max(top,Math.min(top+imgHeight,y1+Math.abs(x2-x1)/aspectRatio*(y2>=y1?1:-1))));x2=Math.round(x2)}function aspectRatioYX(){y2=Math.max(top,Math.min(top+imgHeight,y1+Math.abs(x2-x1)/aspectRatio*(y2>=y1?1:-1)));x2=Math.round(Math.max(left,Math.min(left+imgWidth,x1+Math.abs(y2-y1)*aspectRatio*(x2>=x1?1:-1))));y2=Math.round(y2)}function doResize(newX2,newY2){x2=newX2;y2=newY2;if(options.minWidth&&Math.abs(x2-x1)<options.minWidth){x2=x1-options.minWidth*(x2<x1?1:-1);if(x2<left)x1=left+options.minWidth;else if(x2>left+imgWidth)x1=left+imgWidth-options.minWidth}if(options.minHeight&&Math.abs(y2-y1)<options.minHeight){y2=y1-options.minHeight*(y2<y1?1:-1);if(y2<top)y1=top+options.minHeight;else if(y2>top+imgHeight)y1=top+imgHeight-options.minHeight}x2=Math.max(left,Math.min(x2,left+imgWidth));y2=Math.max(top,Math.min(y2,top+imgHeight));if(aspectRatio)if(Math.abs(x2-x1)/aspectRatio>Math.abs(y2-y1))aspectRatioYX();else aspectRatioXY();if(options.maxWidth&&Math.abs(x2-x1)>options.maxWidth){x2=x1-options.maxWidth*(x2<x1?1:-1);if(aspectRatio)aspectRatioYX()}if(options.maxHeight&&Math.abs(y2-y1)>options.maxHeight){y2=y1-options.maxHeight*(y2<y1?1:-1);if(aspectRatio)aspectRatioXY()}selection.x1=selX(Math.min(x1,x2));selection.x2=selX(Math.max(x1,x2));selection.y1=selY(Math.min(y1,y2));selection.y2=selY(Math.max(y1,y2));selection.width=Math.abs(x2-x1);selection.height=Math.abs(y2-y1);update();options.onSelectChange(img,selection)}function selectingMouseMove(event){x2=!resize.length||resize[H]||aspectRatio?evX(event):viewX(selection.x2);y2=!resize.length||resize[V]||aspectRatio?evY(event):viewY(selection.y2);doResize(x2,y2);return false}function doMove(newX1,newY1){x2=(x1=newX1)+selection.width;y2=(y1=newY1)+selection.height;selection.x1=selX(x1);selection.y1=selY(y1);selection.x2=selX(x2);selection.y2=selY(y2);update();options.onSelectChange(img,selection)}function movingMouseMove(event){var newX1=Math.max(left,Math.min(moveX+evX(event)-startX,left+imgWidth-selection.width));var newY1=Math.max(top,Math.min(moveY+evY(event)-startY,top+imgHeight-selection.height));doMove(newX1,newY1);event.preventDefault();return false}function startSelection(event){adjust();selection.x1=selection.x2=selX(startX=x1=x2=evX(event));selection.y1=selection.y2=selY(startY=y1=y2=evY(event));selection.width=0;selection.height=0;resize=[];update();$a.add($o).show();jQuery(document).unbind('mouseup',cancelSelection).mousemove(selectingMouseMove);$border2.unbind('mousemove',areaMouseMove);options.onSelectStart(img,selection);jQuery(document).one('mouseup',function(){if(options.autoHide||(selection.width*selection.height==0))$a.add($o).hide();options.onSelectEnd(img,selection);jQuery(document).unbind('mousemove',selectingMouseMove);$border2.mousemove(areaMouseMove)})}function cancelSelection(){jQuery(document).unbind('mousemove',startSelection);$a.add($o).hide()}function imgMouseDown(event){if(event.which!=1)return false;jQuery(document).one('mousemove',startSelection).one('mouseup',cancelSelection);return false}function windowResize(){adjust();update(false);x1=viewX(selection.x1);y1=viewY(selection.y1);x2=viewX(selection.x2);y2=viewY(selection.y2)}var docKeyPress=function(event){var k=options.keys,d=10,t,key=event.keyCode||event.which;if(!isNaN(k.arrows))d=k.arrows;if(!isNaN(k.shift)&&event.shiftKey)d=k.shift;if(!isNaN(k.ctrl)&&event.ctrlKey)d=k.ctrl;if(!isNaN(k.alt)&&(event.altKey||event.originalEvent.altKey))d=k.alt;if(k.arrows=='resize'||(k.shift=='resize'&&event.shiftKey)||(k.ctrl=='resize'&&event.ctrlKey)||(k.alt=='resize'&&(event.altKey||event.originalEvent.altKey))){switch(key){case 37:d=-d;case 39:t=Math.max(x1,x2);x1=Math.min(x1,x2);x2=Math.max(t+d,x1);if(aspectRatio)aspectRatioYX();break;case 38:d=-d;case 40:t=Math.max(y1,y2);y1=Math.min(y1,y2);y2=Math.max(t+d,y1);if(aspectRatio)aspectRatioXY();break;default:return}doResize(x2,y2)}else{x1=Math.min(x1,x2);y1=Math.min(y1,y2);switch(key){case 37:doMove(Math.max(x1-d,left),y1);break;case 38:doMove(x1,Math.max(y1-d,top));break;case 39:doMove(x1+Math.min(d,imgWidth-selX(x2)),y1);break;case 40:doMove(x1,y1+Math.min(d,imgHeight-selY(y2)));break;default:return}}return false};this.setOptions=function(newOptions){options=jQuery.extend(options,newOptions);if(newOptions.x1!=null){selection.x1=newOptions.x1;selection.y1=newOptions.y1;selection.x2=newOptions.x2;selection.y2=newOptions.y2;newOptions.show=true}if(newOptions.keys)options.keys=jQuery.extend({shift:1,ctrl:'resize'},newOptions.keys===true?{}:newOptions.keys);parent=jQuery(options.parent).get(0);adjust();$p=jQuery(img);while($p.length&&!$p.is('body')){if(!isNaN($p.css('z-index'))&&$p.css('z-index')>zIndex)zIndex=$p.css('z-index');if($p.css('position')=='fixed')fixed=true;$p=$p.parent()}x1=viewX(selection.x1);y1=viewY(selection.y1);x2=viewX(selection.x2);y2=viewY(selection.y2);selection.width=x2-x1;selection.height=y2-y1;update();if(newOptions.hide)$a.add($o).hide();else if(newOptions.show)$a.add($o).show();$o.addClass(options.classPrefix+'-outer');$area.addClass(options.classPrefix+'-selection');$border1.addClass(options.classPrefix+'-border1');$border2.addClass(options.classPrefix+'-border2');$a.css({borderWidth:options.borderWidth+'px'});$area.css({backgroundColor:options.selectionColor,opacity:options.selectionOpacity});$border1.css({borderStyle:'solid',borderColor:options.borderColor1});$border2.css({borderStyle:'dashed',borderColor:options.borderColor2});$o.css({opacity:options.outerOpacity,backgroundColor:options.outerColor});aspectRatio=options.aspectRatio&&(d=options.aspectRatio.split(/:/))?d[0]/d[1]:null;if(options.disable||options.enable===false){$a.unbind('mousemove',areaMouseMove).unbind('mousedown',areaMouseDown);jQuery(img).add($o).unbind('mousedown',imgMouseDown);jQuery(window).unbind('resize',windowResize)}else if(options.enable||options.disable===false){if(options.resizable||options.movable)$a.mousemove(areaMouseMove).mousedown(areaMouseDown);if(!options.persistent)jQuery(img).add($o).mousedown(imgMouseDown);jQuery(window).resize(windowResize)}jQuery(options.parent).append($o.add($a));options.enable=options.disable=undefined};if(jQuery.browser.msie)jQuery(img).attr('unselectable','on');jQuery.imgAreaSelect.keyPress=jQuery.browser.msie||jQuery.browser.safari?'keydown':'keypress';$a.add($o).css({display:'none',position:fixed?'fixed':'absolute',overflow:'hidden',zIndex:zIndex>0?zIndex:'0'});$area.css({borderStyle:'solid'});initOptions={borderColor1:'#000',borderColor2:'#fff',borderWidth:1,classPrefix:'imgareaselect',movable:true,resizable:true,selectionColor:'#fff',selectionOpacity:0.2,outerColor:'#000',outerOpacity:0.2,parent:'body',onSelectStart:function(){},onSelectChange:function(){},onSelectEnd:function(){}};options=jQuery.extend(initOptions,options);this.setOptions(options)};jQuery.fn.imgAreaSelect=function(options){options=options||{};this.each(function(){if(jQuery(this).data('imgAreaSelect'))jQuery(this).data('imgAreaSelect').setOptions(options);else{if(options.enable===undefined&&options.disable===undefined)options.enable=true;jQuery(this).data('imgAreaSelect',new jQuery.imgAreaSelect.init(this,options))}});return this};

/*
 * jQuery Form Plugin
 * version: 2.17 (06-NOV-2008)
 * @requires jQuery v1.2.2 or later
 *
 * Examples and documentation at: http://malsup.com/jquery/form/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id$
 */
;(function($) {

/*
    Usage Note:  
    -----------
    Do not use both ajaxSubmit and ajaxForm on the same form.  These
    functions are intended to be exclusive.  Use ajaxSubmit if you want
    to bind your own submit handler to the form.  For example,

    $(document).ready(function() {
        $('#myForm').bind('submit', function() {
            $(this).ajaxSubmit({
                target: '#output'
            });
            return false; // <-- important!
        });
    });

    Use ajaxForm when you want the plugin to manage all the event binding
    for you.  For example,

    $(document).ready(function() {
        $('#myForm').ajaxForm({
            target: '#output'
        });
    });
        
    When using ajaxForm, the ajaxSubmit function will be invoked for you
    at the appropriate time.  
*/

/**
 * ajaxSubmit() provides a mechanism for immediately submitting 
 * an HTML form using AJAX.
 */
$.fn.ajaxSubmit = function(options) {
    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
    if (!this.length) {
        log('ajaxSubmit: skipping submit process - no element selected');
        return this;
    }

    if (typeof options == 'function')
        options = { success: options };

    options = $.extend({
        url:  this.attr('action') || window.location.toString(),
        type: this.attr('method') || 'GET'
    }, options || {});

    // hook for manipulating the form data before it is extracted;
    // convenient for use with rich editors like tinyMCE or FCKEditor
    var veto = {};
    this.trigger('form-pre-serialize', [this, options, veto]);
    if (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
        return this;
    }

    // provide opportunity to alter form data before it is serialized
    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
        log('ajaxSubmit: submit aborted via beforeSerialize callback');
        return this;
    }    
   
    var a = this.formToArray(options.semantic);
    if (options.data) {
        options.extraData = options.data;
        for (var n in options.data) {
          if(options.data[n] instanceof Array) {
            for (var k in options.data[n])
              a.push( { name: n, value: options.data[n][k] } )
          }  
          else
             a.push( { name: n, value: options.data[n] } );
        }
    }

    // give pre-submit callback an opportunity to abort the submit
    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
        log('ajaxSubmit: submit aborted via beforeSubmit callback');
        return this;
    }    

    // fire vetoable 'validate' event
    this.trigger('form-submit-validate', [a, this, options, veto]);
    if (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
        return this;
    }    

    var q = $.param(a);

    if (options.type.toUpperCase() == 'GET') {
        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
        options.data = null;  // data is null for 'get'
    }
    else
        options.data = q; // data is the query string for 'post'

    var $form = this, callbacks = [];
    if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
    if (options.clearForm) callbacks.push(function() { $form.clearForm(); });

    // perform a load on the target only if dataType is not provided
    if (!options.dataType && options.target) {
        var oldSuccess = options.success || function(){};
        callbacks.push(function(data) {
            $(options.target).html(data).each(oldSuccess, arguments);
        });
    }
    else if (options.success)
        callbacks.push(options.success);

    options.success = function(data, status) {
        for (var i=0, max=callbacks.length; i < max; i++)
            callbacks[i].apply(options, [data, status, $form]);
    };

    // are there files to upload?
    var files = $('input:file', this).fieldValue();
    var found = false;
    for (var j=0; j < files.length; j++)
        if (files[j])
            found = true;

    // options.iframe allows user to force iframe mode
   if (options.iframe || found) { 
       // hack to fix Safari hang (thanks to Tim Molendijk for this)
       // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
       if ($.browser.safari && options.closeKeepAlive)
           $.get(options.closeKeepAlive, fileUpload);
       else
           fileUpload();
       }
   else
       $.ajax(options);

    // fire 'notify' event
    this.trigger('form-submit-notify', [this, options]);
    return this;


    // private function for handling file uploads (hat tip to YAHOO!)
    function fileUpload() {
        var form = $form[0];
        
        if ($(':input[@name=submit]', form).length) {
            alert('Error: Form elements must not be named "submit".');
            return;
        }
        
        var opts = $.extend({}, $.ajaxSettings, options);
		var s = jQuery.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);

        var id = 'jqFormIO' + (new Date().getTime());
        var $io = $('<iframe id="' + id + '" name="' + id + '" />');
        var io = $io[0];

        if ($.browser.msie || $.browser.opera) 
            io.src = 'javascript:false;document.write("");';
        $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

        var xhr = { // mock object
            aborted: 0,
            responseText: null,
            responseXML: null,
            status: 0,
            statusText: 'n/a',
            getAllResponseHeaders: function() {},
            getResponseHeader: function() {},
            setRequestHeader: function() {},
            abort: function() { 
                this.aborted = 1; 
                $io.attr('src','about:blank'); // abort op in progress
            }
        };

        var g = opts.global;
        // trigger ajax global events so that activity/block indicators work like normal
        if (g && ! $.active++) $.event.trigger("ajaxStart");
        if (g) $.event.trigger("ajaxSend", [xhr, opts]);

		if (s.beforeSend && s.beforeSend(xhr, s) === false) {
			s.global && jQuery.active--;
			return;
        }
        if (xhr.aborted)
            return;
        
        var cbInvoked = 0;
        var timedOut = 0;

        // add submitting element to data if we know it
        var sub = form.clk;
        if (sub) {
            var n = sub.name;
            if (n && !sub.disabled) {
                options.extraData = options.extraData || {};
                options.extraData[n] = sub.value;
                if (sub.type == "image") {
                    options.extraData[name+'.x'] = form.clk_x;
                    options.extraData[name+'.y'] = form.clk_y;
                }
            }
        }

        // take a breath so that pending repaints get some cpu time before the upload starts
        setTimeout(function() {
            // make sure form attrs are set
            var t = $form.attr('target'), a = $form.attr('action');
            $form.attr({
                target:   id,
                method:   'POST',
                action:   opts.url
            });
            
            // ie borks in some cases when setting encoding
            if (! options.skipEncodingOverride) {
                $form.attr({
                    encoding: 'multipart/form-data',
                    enctype:  'multipart/form-data'
                });
            }

            // support timout
            if (opts.timeout)
                setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

            // add "extra" data to form if provided in options
            var extraInputs = [];
            try {
                if (options.extraData)
                    for (var n in options.extraData)
                        extraInputs.push(
                            $('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
                                .appendTo(form)[0]);
            
                // add iframe to doc and submit the form
                $io.appendTo('body');
                io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
                form.submit();
            }
            finally {
                // reset attrs and remove "extra" input elements
                $form.attr('action', a);
                t ? $form.attr('target', t) : $form.removeAttr('target');
                $(extraInputs).remove();
            }
        }, 10);

        function cb() {
            if (cbInvoked++) return;
            
            io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);

            var operaHack = 0;
            var ok = true;
            try {
                if (timedOut) throw 'timeout';
                // extract the server response from the iframe
                var data, doc;

                doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
                
                if (doc.body == null && !operaHack && $.browser.opera) {
                    // In Opera 9.2.x the iframe DOM is not always traversable when
                    // the onload callback fires so we give Opera 100ms to right itself
                    operaHack = 1;
                    cbInvoked--;
                    setTimeout(cb, 100);
                    return;
                }
                
                xhr.responseText = doc.body ? doc.body.innerHTML : null;
                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
                xhr.getResponseHeader = function(header){
                    var headers = {'content-type': opts.dataType};
                    return headers[header];
                };

                if (opts.dataType == 'json' || opts.dataType == 'script') {
                    var ta = doc.getElementsByTagName('textarea')[0];
                    xhr.responseText = ta ? ta.value : xhr.responseText;
                }
                else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
                    xhr.responseXML = toXml(xhr.responseText);
                }
                data = $.httpData(xhr, opts.dataType);
            }
            catch(e){
                ok = false;
                $.handleError(opts, xhr, 'error', e);
            }

            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
            if (ok) {
                opts.success(data, 'success');
                if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
            }
            if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
            if (g && ! --$.active) $.event.trigger("ajaxStop");
            if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');

            // clean up
            setTimeout(function() {
                $io.remove();
                xhr.responseXML = null;
            }, 100);
        };

        function toXml(s, doc) {
            if (window.ActiveXObject) {
                doc = new ActiveXObject('Microsoft.XMLDOM');
                doc.async = 'false';
                doc.loadXML(s);
            }
            else
                doc = (new DOMParser()).parseFromString(s, 'text/xml');
            return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
        };
    };
};

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements (if the element
 *    is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the element that was
 *    used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
 * passes the options argument along after properly binding events for submit elements and
 * the form itself.
 */ 
$.fn.ajaxForm = function(options) {
    return this.ajaxFormUnbind().bind('submit.form-plugin',function() {
        $(this).ajaxSubmit(options);
        return false;
    }).each(function() {
        // store options in hash
        $(":submit,input:image", this).bind('click.form-plugin',function(e) {
            var form = this.form;
            form.clk = this;
            if (this.type == 'image') {
                if (e.offsetX != undefined) {
                    form.clk_x = e.offsetX;
                    form.clk_y = e.offsetY;
                } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
                    var offset = $(this).offset();
                    form.clk_x = e.pageX - offset.left;
                    form.clk_y = e.pageY - offset.top;
                } else {
                    form.clk_x = e.pageX - this.offsetLeft;
                    form.clk_y = e.pageY - this.offsetTop;
                }
            }
            // clear form vars
            setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 10);
        });
    });
};

// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() {
    this.unbind('submit.form-plugin');
    return this.each(function() {
        $(":submit,input:image", this).unbind('click.form-plugin');
    });

};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.  An example of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * It is this array that is passed to pre-submit callback functions provided to the
 * ajaxSubmit() and ajaxForm() methods.
 */
$.fn.formToArray = function(semantic) {
    var a = [];
    if (this.length == 0) return a;

    var form = this[0];
    var els = semantic ? form.getElementsByTagName('*') : form.elements;
    if (!els) return a;
    for(var i=0, max=els.length; i < max; i++) {
        var el = els[i];
        var n = el.name;
        if (!n) continue;

        if (semantic && form.clk && el.type == "image") {
            // handle image inputs on the fly when semantic == true
            if(!el.disabled && form.clk == el)
                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
            continue;
        }

        var v = $.fieldValue(el, true);
        if (v && v.constructor == Array) {
            for(var j=0, jmax=v.length; j < jmax; j++)
                a.push({name: n, value: v[j]});
        }
        else if (v !== null && typeof v != 'undefined')
            a.push({name: n, value: v});
    }

    if (!semantic && form.clk) {
        // input type=='image' are not found in elements array! handle them here
        var inputs = form.getElementsByTagName("input");
        for(var i=0, max=inputs.length; i < max; i++) {
            var input = inputs[i];
            var n = input.name;
            if(n && !input.disabled && input.type == "image" && form.clk == input)
                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
        }
    }
    return a;
};

/**
 * Serializes form data into a 'submittable' string. This method will return a string
 * in the format: name1=value1&amp;name2=value2
 */
$.fn.formSerialize = function(semantic) {
    //hand off to jQuery.param for proper encoding
    return $.param(this.formToArray(semantic));
};

/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 */
$.fn.fieldSerialize = function(successful) {
    var a = [];
    this.each(function() {
        var n = this.name;
        if (!n) return;
        var v = $.fieldValue(this, successful);
        if (v && v.constructor == Array) {
            for (var i=0,max=v.length; i < max; i++)
                a.push({name: n, value: v[i]});
        }
        else if (v !== null && typeof v != 'undefined')
            a.push({name: this.name, value: v});
    });
    //hand off to jQuery.param for proper encoding
    return $.param(a);
};

/**
 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
 *
 *  <form><fieldset>
 *      <input name="A" type="text" />
 *      <input name="A" type="text" />
 *      <input name="B" type="checkbox" value="B1" />
 *      <input name="B" type="checkbox" value="B2"/>
 *      <input name="C" type="radio" value="C1" />
 *      <input name="C" type="radio" value="C2" />
 *  </fieldset></form>
 *
 *  var v = $(':text').fieldValue();
 *  // if no values are entered into the text inputs
 *  v == ['','']
 *  // if values entered into the text inputs are 'foo' and 'bar'
 *  v == ['foo','bar']
 *
 *  var v = $(':checkbox').fieldValue();
 *  // if neither checkbox is checked
 *  v === undefined
 *  // if both checkboxes are checked
 *  v == ['B1', 'B2']
 *
 *  var v = $(':radio').fieldValue();
 *  // if neither radio is checked
 *  v === undefined
 *  // if first radio is checked
 *  v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If this value is false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.  If no valid value can be determined the
 *       array will be empty, otherwise it will contain one or more values.
 */
$.fn.fieldValue = function(successful) {
    for (var val=[], i=0, max=this.length; i < max; i++) {
        var el = this[i];
        var v = $.fieldValue(el, successful);
        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
            continue;
        v.constructor == Array ? $.merge(val, v) : val.push(v);
    }
    return val;
};

/**
 * Returns the value of the field element.
 */
$.fieldValue = function(el, successful) {
    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
    if (typeof successful == 'undefined') successful = true;

    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
        (t == 'checkbox' || t == 'radio') && !el.checked ||
        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
        tag == 'select' && el.selectedIndex == -1))
            return null;

    if (tag == 'select') {
        var index = el.selectedIndex;
        if (index < 0) return null;
        var a = [], ops = el.options;
        var one = (t == 'select-one');
        var max = (one ? index+1 : ops.length);
        for(var i=(one ? index : 0); i < max; i++) {
            var op = ops[i];
            if (op.selected) {
                // extra pain for IE...
                var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
                if (one) return v;
                a.push(v);
            }
        }
        return a;
    }
    return el.value;
};

/**
 * Clears the form data.  Takes the following actions on the form's input fields:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 */
$.fn.clearForm = function() {
    return this.each(function() {
        $('input,select,textarea', this).clearFields();
    });
};

/**
 * Clears the selected form elements.
 */
$.fn.clearFields = $.fn.clearInputs = function() {
    return this.each(function() {
        var t = this.type, tag = this.tagName.toLowerCase();
        if (t == 'text' || t == 'password' || tag == 'textarea')
            this.value = '';
        else if (t == 'checkbox' || t == 'radio')
            this.checked = false;
        else if (tag == 'select')
            this.selectedIndex = -1;
    });
};

/**
 * Resets the form data.  Causes all form elements to be reset to their original value.
 */
$.fn.resetForm = function() {
    return this.each(function() {
        // guard against an input with the name of 'reset'
        // note that IE reports the reset function as an 'object'
        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
            this.reset();
    });
};

/**
 * Enables or disables any matching elements.
 */
$.fn.enable = function(b) { 
    if (b == undefined) b = true;
    return this.each(function() { 
        this.disabled = !b 
    });
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 */
$.fn.selected = function(select) {
    if (select == undefined) select = true;
    return this.each(function() { 
        var t = this.type;
        if (t == 'checkbox' || t == 'radio')
            this.checked = select;
        else if (this.tagName.toLowerCase() == 'option') {
            var $sel = $(this).parent('select');
            if (select && $sel[0] && $sel[0].type == 'select-one') {
                // deselect all other options
                $sel.find('option').selected(false);
            }
            this.selected = select;
        }
    });
};

// helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() {
    if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
        window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
};

})(jQuery);

/**
* @author Remy Sharp
* @url http://remysharp.com/2007/01/25/jquery-tutorial-text-box-hints/
*/

(function ($) {

$.fn.hint = function (blurClass) {
 if (!blurClass) blurClass = 'blur';

 return this.each(function () {
 // get jQuery instance of 'this'
 var $$ = $(this);

 // get it once since it won't change
 var title = $$.attr('title');

 // only apply logic if the element has the attribute
 if (title) {

 // Note this is a one liner

 // on blur, set value to title attr if text is blank
 $$.blur(function () {
 if ($$.val() == '') {
 $$.val(title).addClass(blurClass);
 }
 })

 // on focus, set value to blank if current value matches title attr
 .focus(function () {
 if ($$.val() == title) {
 $$.val('').removeClass(blurClass);
 }
 })

 // clear the pre-defined text when form is submitted
 .parents('form:first').submit(function () {
 if ($$.val() == title) {
 $$.val('').removeClass(blurClass);
 }
 }).end()

 // now change all inputs to title
 .blur();

 // counteracts the effect of Firefox's autocomplete stripping the blur effect
 if ($.browser.mozilla && !$$.attr('autocomplete')) {
 setTimeout(function () {
 if ($$.val() == title) $$.val('');
 $$.blur();
 }, 10);
 }
 }
 });
};

})(jQuery);

/**
*
*	simpleTooltip jQuery plugin, by Marius ILIE
*	visit http://dev.mariusilie.net for details
*
**/
(function($){ $.fn.simpletooltip = function(){
	return this.each(function() {
		var text = $(this).attr("title");
		$(this).attr("title", "");
		if(text != undefined) {
			$(this).hover(function(e){
				var tipX = e.pageX + 12;
				var tipY = e.pageY + 12;
				$(this).attr("title", ""); 
				$("body").append("<div id='simpleTooltip' style='position: absolute; z-index: 100; display: none;'>" + text + "</div>");
				if($.browser.msie) var tipWidth = $("#simpleTooltip").outerWidth(true)
				else var tipWidth = $("#simpleTooltip").width()
				$("#simpleTooltip").width(tipWidth);
				$("#simpleTooltip").css("left", tipX).css("top", tipY).fadeIn("medium");
			}, function(){
				$("#simpleTooltip").remove();
				$(this).attr("title", text);
			});
			$(this).mousemove(function(e){
				var tipX = e.pageX + 12;
				var tipY = e.pageY + 12;
				var tipWidth = $("#simpleTooltip").outerWidth(true);
				var tipHeight = $("#simpleTooltip").outerHeight(true);
				if(tipX + tipWidth > $(window).scrollLeft() + $(window).width()) tipX = e.pageX - tipWidth;
				if($(window).height()+$(window).scrollTop() < tipY + tipHeight) tipY = e.pageY - tipHeight;
				$("#simpleTooltip").css("left", tipX).css("top", tipY).fadeIn("medium");
			});
		}
	});
}})(jQuery);

/**
 * jQuery lightBox plugin
 * This jQuery plugin was inspired and based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/)
 * and adapted to me for use like a plugin from jQuery.
 * @name jquery-lightbox-0.5.js
 * @author Leandro Vieira Pinho - http://leandrovieira.com
 * @version 0.5
 * @date April 11, 2008
 * @category jQuery plugin
 * @copyright (c) 2008 Leandro Vieira Pinho (leandrovieira.com)
 * @license CC Attribution-No Derivative Works 2.5 Brazil - http://creativecommons.org/licenses/by-nd/2.5/br/deed.en_US
 * @example Visit http://leandrovieira.com/projects/jquery/lightbox/ for more informations about this jQuery plugin
 */

// Offering a Custom Alias suport - More info: http://docs.jquery.com/Plugins/Authoring#Custom_Alias
(function($) {
	/**
	 * $ is an alias to jQuery object
	 *
	 */
	$.fn.lightBox = function(settings) {
		// Settings to configure the jQuery lightBox plugin how you like
		settings = jQuery.extend({
			// Configuration related to overlay
			overlayBgColor: 		'#000',		// (string) Background color to overlay; inform a hexadecimal value like: #RRGGBB. Where RR, GG, and BB are the hexadecimal values for the red, green, and blue values of the color.
			overlayOpacity:			0.8,		// (integer) Opacity value to overlay; inform: 0.X. Where X are number from 0 to 9
			// Configuration related to navigation
			fixedNavigation:		false,		// (boolean) Boolean that informs if the navigation (next and prev button) will be fixed or not in the interface.
			// Configuration related to images
			imageLoading:			'images/lightbox-ico-loading.gif',		// (string) Path and the name of the loading icon
			imageBtnPrev:			'images/lightbox-btn-prev.gif',			// (string) Path and the name of the prev button image
			imageBtnNext:			'images/lightbox-btn-next.gif',			// (string) Path and the name of the next button image
			imageBtnClose:			'images/lightbox-btn-close.gif',		// (string) Path and the name of the close btn
			imageBlank:				'images/lightbox-blank.gif',			// (string) Path and the name of a blank image (one pixel)
			// Configuration related to container image box
			containerBorderSize:	10,			// (integer) If you adjust the padding in the CSS for the container, #lightbox-container-image-box, you will need to update this value
			containerResizeSpeed:	400,		// (integer) Specify the resize duration of container image. These number are miliseconds. 400 is default.
			// Configuration related to texts in caption. For example: Image 2 of 8. You can alter either "Image" and "of" texts.
			txtImage:				'Image',	// (string) Specify text "Image"
			txtOf:					'of',		// (string) Specify text "of"
			// Configuration related to keyboard navigation
			keyToClose:				'c',		// (string) (c = close) Letter to close the jQuery lightBox interface. Beyond this letter, the letter X and the SCAPE key is used to.
			keyToPrev:				'p',		// (string) (p = previous) Letter to show the previous image
			keyToNext:				'n',		// (string) (n = next) Letter to show the next image.
			// Don´t alter these variables in any way
			imageArray:				[],
			activeImage:			0
		},settings);
		// Caching the jQuery object with all elements matched
		var jQueryMatchedObj = this; // This, in this context, refer to jQuery object
		/**
		 * Initializing the plugin calling the start function
		 *
		 * @return boolean false
		 */
		function _initialize() {
			_start(this,jQueryMatchedObj); // This, in this context, refer to object (link) which the user have clicked
			return false; // Avoid the browser following the link
		}
		/**
		 * Start the jQuery lightBox plugin
		 *
		 * @param object objClicked The object (link) whick the user have clicked
		 * @param object jQueryMatchedObj The jQuery object with all elements matched
		 */
		function _start(objClicked,jQueryMatchedObj) {
			// Hime some elements to avoid conflict with overlay in IE. These elements appear above the overlay.
			$('embed, object, select').css({ 'visibility' : 'hidden' });
			// Call the function to create the markup structure; style some elements; assign events in some elements.
			_set_interface();
			// Unset total images in imageArray
			settings.imageArray.length = 0;
			// Unset image active information
			settings.activeImage = 0;
			// We have an image set? Or just an image? Let´s see it.
			if ( jQueryMatchedObj.length == 1 ) {
				settings.imageArray.push(new Array(objClicked.getAttribute('href'),objClicked.getAttribute('title')));
			} else {
				// Add an Array (as many as we have), with href and title atributes, inside the Array that storage the images references		
				for ( var i = 0; i < jQueryMatchedObj.length; i++ ) {
					settings.imageArray.push(new Array(jQueryMatchedObj[i].getAttribute('href'),jQueryMatchedObj[i].getAttribute('title')));
				}
			}
			while ( settings.imageArray[settings.activeImage][0] != objClicked.getAttribute('href') ) {
				settings.activeImage++;
			}
			// Call the function that prepares image exibition
			_set_image_to_view();
		}
		/**
		 * Create the jQuery lightBox plugin interface
		 *
		 * The HTML markup will be like that:
			<div id="jquery-overlay"></div>
			<div id="jquery-lightbox">
				<div id="lightbox-container-image-box">
					<div id="lightbox-container-image">
						<img src="../fotos/XX.jpg" id="lightbox-image">
						<div id="lightbox-nav">
							<a href="#" id="lightbox-nav-btnPrev"></a>
							<a href="#" id="lightbox-nav-btnNext"></a>
						</div>
						<div id="lightbox-loading">
							<a href="#" id="lightbox-loading-link">
								<img src="../images/lightbox-ico-loading.gif">
							</a>
						</div>
					</div>
				</div>
				<div id="lightbox-container-image-data-box">
					<div id="lightbox-container-image-data">
						<div id="lightbox-image-details">
							<span id="lightbox-image-details-caption"></span>
							<span id="lightbox-image-details-currentNumber"></span>
						</div>
						<div id="lightbox-secNav">
							<a href="#" id="lightbox-secNav-btnClose">
								<img src="../images/lightbox-btn-close.gif">
							</a>
						</div>
					</div>
				</div>
			</div>
		 *
		 */
		function _set_interface() {
			// Apply the HTML markup into body tag
			$('body').append('<div id="jquery-overlay"></div><div id="jquery-lightbox"><div id="lightbox-container-image-box"><div id="lightbox-container-image"><img id="lightbox-image"><div style="" id="lightbox-nav"><a href="#" id="lightbox-nav-btnPrev"></a><a href="#" id="lightbox-nav-btnNext"></a></div><div id="lightbox-loading"><a href="#" id="lightbox-loading-link"><img src="' + settings.imageLoading + '"></a></div></div></div><div id="lightbox-container-image-data-box"><div id="lightbox-container-image-data"><div id="lightbox-image-details"><span id="lightbox-image-details-caption"></span><span id="lightbox-image-details-currentNumber"></span></div><div id="lightbox-secNav"><a href="#" id="lightbox-secNav-btnClose"><img src="' + settings.imageBtnClose + '"></a></div></div></div></div>');	
			// Get page sizes
			var arrPageSizes = ___getPageSize();
			// Style overlay and show it
			$('#jquery-overlay').css({
				backgroundColor:	settings.overlayBgColor,
				opacity:			settings.overlayOpacity,
				width:				arrPageSizes[0],
				height:				arrPageSizes[1]
			}).fadeIn();
			// Get page scroll
			var arrPageScroll = ___getPageScroll();
			// Calculate top and left offset for the jquery-lightbox div object and show it
			$('#jquery-lightbox').css({
				top:	arrPageScroll[1] + (arrPageSizes[3] / 10),
				left:	arrPageScroll[0]
			}).show();
			// Assigning click events in elements to close overlay
			$('#jquery-overlay,#jquery-lightbox').click(function() {
				_finish();									
			});
			// Assign the _finish function to lightbox-loading-link and lightbox-secNav-btnClose objects
			$('#lightbox-loading-link,#lightbox-secNav-btnClose').click(function() {
				_finish();
				return false;
			});
			// If window was resized, calculate the new overlay dimensions
			$(window).resize(function() {
				// Get page sizes
				var arrPageSizes = ___getPageSize();
				// Style overlay and show it
				$('#jquery-overlay').css({
					width:		arrPageSizes[0],
					height:		arrPageSizes[1]
				});
				// Get page scroll
				var arrPageScroll = ___getPageScroll();
				// Calculate top and left offset for the jquery-lightbox div object and show it
				$('#jquery-lightbox').css({
					top:	arrPageScroll[1] + (arrPageSizes[3] / 10),
					left:	arrPageScroll[0]
				});
			});
		}
		/**
		 * Prepares image exibition; doing a image´s preloader to calculate it´s size
		 *
		 */
		function _set_image_to_view() { // show the loading
			// Show the loading
			$('#lightbox-loading').show();
			if ( settings.fixedNavigation ) {
				$('#lightbox-image,#lightbox-container-image-data-box,#lightbox-image-details-currentNumber').hide();
			} else {
				// Hide some elements
				$('#lightbox-image,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-container-image-data-box,#lightbox-image-details-currentNumber').hide();
			}
			// Image preload process
			var objImagePreloader = new Image();
			objImagePreloader.onload = function() {
				$('#lightbox-image').attr('src',settings.imageArray[settings.activeImage][0]);
				// Perfomance an effect in the image container resizing it
				_resize_container_image_box(objImagePreloader.width,objImagePreloader.height);
				//	clear onLoad, IE behaves irratically with animated gifs otherwise
				objImagePreloader.onload=function(){};
			};
			objImagePreloader.src = settings.imageArray[settings.activeImage][0];
		};
		/**
		 * Perfomance an effect in the image container resizing it
		 *
		 * @param integer intImageWidth The image´s width that will be showed
		 * @param integer intImageHeight The image´s height that will be showed
		 */
		function _resize_container_image_box(intImageWidth,intImageHeight) {
			// Get current width and height
			var intCurrentWidth = $('#lightbox-container-image-box').width();
			var intCurrentHeight = $('#lightbox-container-image-box').height();
			// Get the width and height of the selected image plus the padding
			var intWidth = (intImageWidth + (settings.containerBorderSize * 2)); // Plus the image´s width and the left and right padding value
			var intHeight = (intImageHeight + (settings.containerBorderSize * 2)); // Plus the image´s height and the left and right padding value
			// Diferences
			var intDiffW = intCurrentWidth - intWidth;
			var intDiffH = intCurrentHeight - intHeight;
			// Perfomance the effect
			$('#lightbox-container-image-box').animate({ width: intWidth, height: intHeight },settings.containerResizeSpeed,function() { _show_image(); });
			if ( ( intDiffW == 0 ) && ( intDiffH == 0 ) ) {
				if ( $.browser.msie ) {
					___pause(250);
				} else {
					___pause(100);	
				}
			} 
			$('#lightbox-container-image-data-box').css({ width: intImageWidth+20 });
			$('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ height: intImageHeight + (settings.containerBorderSize * 2) });
		};
		/**
		 * Show the prepared image
		 *
		 */
		function _show_image() {
			$('#lightbox-loading').hide();
			$('#lightbox-image').fadeIn(function() {
				_show_image_data();
				_set_navigation();
			});
			_preload_neighbor_images();
		};
		/**
		 * Show the image information
		 *
		 */
		function _show_image_data() {
			$('#lightbox-container-image-data-box').slideDown('fast');
			$('#lightbox-image-details-caption').hide();
			if ( settings.imageArray[settings.activeImage][1] ) {
				$('#lightbox-image-details-caption').html(settings.imageArray[settings.activeImage][1]).show();
			}
			// If we have a image set, display 'Image X of X'
			if ( settings.imageArray.length > 1 ) {
				$('#lightbox-image-details-currentNumber').html(settings.txtImage + ' ' + ( settings.activeImage + 1 ) + ' ' + settings.txtOf + ' ' + settings.imageArray.length).show();
			}		
		}
		/**
		 * Display the button navigations
		 *
		 */
		function _set_navigation() {
			$('#lightbox-nav').show();

			// Instead to define this configuration in CSS file, we define here. And it´s need to IE. Just.
			$('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
			
			// Show the prev button, if not the first image in set
			if ( settings.activeImage != 0 ) {
				if ( settings.fixedNavigation ) {
					$('#lightbox-nav-btnPrev').css({ 'background' : 'url(' + settings.imageBtnPrev + ') left 15% no-repeat' })
						.unbind()
						.bind('click',function() {
							settings.activeImage = settings.activeImage - 1;
							_set_image_to_view();
							return false;
						});
				} else {
					// Show the images button for Next buttons
					$('#lightbox-nav-btnPrev').unbind().hover(function() {
						$(this).css({ 'background' : 'url(' + settings.imageBtnPrev + ') left 15% no-repeat' });
					},function() {
						$(this).css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
					}).show().bind('click',function() {
						settings.activeImage = settings.activeImage - 1;
						_set_image_to_view();
						return false;
					});
				}
			}
			
			// Show the next button, if not the last image in set
			if ( settings.activeImage != ( settings.imageArray.length -1 ) ) {
				if ( settings.fixedNavigation ) {
					$('#lightbox-nav-btnNext').css({ 'background' : 'url(' + settings.imageBtnNext + ') right 15% no-repeat' })
						.unbind()
						.bind('click',function() {
							settings.activeImage = settings.activeImage + 1;
							_set_image_to_view();
							return false;
						});
				} else {
					// Show the images button for Next buttons
					$('#lightbox-nav-btnNext').unbind().hover(function() {
						$(this).css({ 'background' : 'url(' + settings.imageBtnNext + ') right 15% no-repeat' });
					},function() {
						$(this).css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
					}).show().bind('click',function() {
						settings.activeImage = settings.activeImage + 1;
						_set_image_to_view();
						return false;
					});
				}
			}
			// Enable keyboard navigation
			_enable_keyboard_navigation();
		}
		/**
		 * Enable a support to keyboard navigation
		 *
		 */
		function _enable_keyboard_navigation() {
			$(document).keydown(function(objEvent) {
				_keyboard_action(objEvent);
			});
		}
		/**
		 * Disable the support to keyboard navigation
		 *
		 */
		function _disable_keyboard_navigation() {
			$(document).unbind();
		}
		/**
		 * Perform the keyboard actions
		 *
		 */
		function _keyboard_action(objEvent) {
			// To ie
			if ( objEvent == null ) {
				keycode = event.keyCode;
				escapeKey = 27;
			// To Mozilla
			} else {
				keycode = objEvent.keyCode;
				escapeKey = objEvent.DOM_VK_ESCAPE;
			}
			// Get the key in lower case form
			key = String.fromCharCode(keycode).toLowerCase();
			// Verify the keys to close the ligthBox
			if ( ( key == settings.keyToClose ) || ( key == 'x' ) || ( keycode == escapeKey ) ) {
				_finish();
			}
			// Verify the key to show the previous image
			if ( ( key == settings.keyToPrev ) || ( keycode == 37 ) ) {
				// If we´re not showing the first image, call the previous
				if ( settings.activeImage != 0 ) {
					settings.activeImage = settings.activeImage - 1;
					_set_image_to_view();
					_disable_keyboard_navigation();
				}
			}
			// Verify the key to show the next image
			if ( ( key == settings.keyToNext ) || ( keycode == 39 ) ) {
				// If we´re not showing the last image, call the next
				if ( settings.activeImage != ( settings.imageArray.length - 1 ) ) {
					settings.activeImage = settings.activeImage + 1;
					_set_image_to_view();
					_disable_keyboard_navigation();
				}
			}
		}
		/**
		 * Preload prev and next images being showed
		 *
		 */
		function _preload_neighbor_images() {
			if ( (settings.imageArray.length -1) > settings.activeImage ) {
				objNext = new Image();
				objNext.src = settings.imageArray[settings.activeImage + 1][0];
			}
			if ( settings.activeImage > 0 ) {
				objPrev = new Image();
				objPrev.src = settings.imageArray[settings.activeImage -1][0];
			}
		}
		/**
		 * Remove jQuery lightBox plugin HTML markup
		 *
		 */
		function _finish() {
			$('#jquery-lightbox').remove();
			$('#jquery-overlay').fadeOut(function() { $('#jquery-overlay').remove(); });
			// Show some elements to avoid conflict with overlay in IE. These elements appear above the overlay.
			$('embed, object, select').css({ 'visibility' : 'visible' });
		}
		/**
		 / THIRD FUNCTION
		 * getPageSize() by quirksmode.com
		 *
		 * @return Array Return an array with page width, height and window width, height
		 */
		function ___getPageSize() {
			var xScroll, yScroll;
			if (window.innerHeight && window.scrollMaxY) {	
				xScroll = window.innerWidth + window.scrollMaxX;
				yScroll = window.innerHeight + window.scrollMaxY;
			} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
				xScroll = document.body.scrollWidth;
				yScroll = document.body.scrollHeight;
			} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
				xScroll = document.body.offsetWidth;
				yScroll = document.body.offsetHeight;
			}
			var windowWidth, windowHeight;
			if (self.innerHeight) {	// all except Explorer
				if(document.documentElement.clientWidth){
					windowWidth = document.documentElement.clientWidth; 
				} else {
					windowWidth = self.innerWidth;
				}
				windowHeight = self.innerHeight;
			} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
				windowWidth = document.documentElement.clientWidth;
				windowHeight = document.documentElement.clientHeight;
			} else if (document.body) { // other Explorers
				windowWidth = document.body.clientWidth;
				windowHeight = document.body.clientHeight;
			}	
			// for small pages with total height less then height of the viewport
			if(yScroll < windowHeight){
				pageHeight = windowHeight;
			} else { 
				pageHeight = yScroll;
			}
			// for small pages with total width less then width of the viewport
			if(xScroll < windowWidth){	
				pageWidth = xScroll;		
			} else {
				pageWidth = windowWidth;
			}
			arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight);
			return arrayPageSize;
		};
		/**
		 / THIRD FUNCTION
		 * getPageScroll() by quirksmode.com
		 *
		 * @return Array Return an array with x,y page scroll values.
		 */
		function ___getPageScroll() {
			var xScroll, yScroll;
			if (self.pageYOffset) {
				yScroll = self.pageYOffset;
				xScroll = self.pageXOffset;
			} else if (document.documentElement && document.documentElement.scrollTop) {	 // Explorer 6 Strict
				yScroll = document.documentElement.scrollTop;
				xScroll = document.documentElement.scrollLeft;
			} else if (document.body) {// all other Explorers
				yScroll = document.body.scrollTop;
				xScroll = document.body.scrollLeft;	
			}
			arrayPageScroll = new Array(xScroll,yScroll);
			return arrayPageScroll;
		};
		 /**
		  * Stop the code execution from a escified time in milisecond
		  *
		  */
		 function ___pause(ms) {
			var date = new Date(); 
			curDate = null;
			do { var curDate = new Date(); }
			while ( curDate - date < ms);
		 };
		// Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
		return this.unbind('click').click(_initialize);
	};
})(jQuery); // Call and execute the function immediately passing the jQuery object
